package com.cqrcb.cloud.config.context;

import com.alibaba.fastjson.JSONObject;
import com.cqrcb.cloud.config.annotation.CustomChain;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;

/**
 * @author ：29520
 * @date ：Created in 2021/10/18 20:24
 * @description：
 * @modified By：
 * @version:
 */
@Component
public class ApplicationContextUtil implements ApplicationContextAware, ApplicationContextInitializer<ConfigurableApplicationContext> {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void initChain(){
//        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(CustomChain.class);
//        for (String key : beansWithAnnotation.keySet()) {
//            String scanPackage = "com.pkk";
//            //获取指定bean的注解为EnableRetryRabbitMq.class的注解属性
//            final CustomChain annotation = AnnotationUtils.findAnnotation(beansWithAnnotation.get(key).getClass(), CustomChain.class);
//            if (null != annotation && StringUtils.isNotBlank(annotation.scanBasePackages())) {
//                scanPackage = annotation.scanBasePackages();
//            }
//            //注入bean（自己封装的方法,详情看下面）
//            RetrySpringUtil.handleRegisterBeanWithSpringToInitConfigurerationBean(applicationContext);
//        }

//        //获取自定义注解的配置
//        final Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(CustomChain.class);
//        for (String key : beansWithAnnotation.keySet()) {
//            //Spring 代理类导致Method无法获取,这里使用AopUtils.getTargetClass()方法
//            Method[] methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(beansWithAnnotation.get(key).getClass()));
//            for (Method method : methods) {
//                //获取指定方法上的注解的属性
//                final CustomChain chain = AnnotationUtils.findAnnotation(method, CustomChain.class);
//                if (null != chain) {
//                    System.out.println("--------->" + method + "  " + chain);
////                    //验证必要的注解的属性
////                    String queueName = Optional.ofNullable(initRetryRabbitMq.queueName()).orElseThrow(() -> new IllegalArgumentException("Please specify the queue name of the queue!"));
////
////                    //多个bean的时候相当于起个别名
////                    String registerBean = queueName + "InitConfigurerationBean";
////
////                    //将bean注册到Spring容器中,通过构造函数的方式进行注入
////                    SpringRegisterBean.registerBean((ConfigurableApplicationContext) applicationContext, registerBean, InitConfigurerationBean.class, initRetryRabbitMq, applicationContext);
////                    log.info("The registration bean is " + registerBean + ",Configuration information is " + JSONObject.toJSONString(initRetryRabbitMq));
//                }
//            }
//        }

        String[] beanNames = applicationContext.getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            final Class clazz = applicationContext.getType(beanName);
//            addExpires(clazz, expires);
            ReflectionUtils.doWithMethods(clazz, method -> {
                ReflectionUtils.makeAccessible(method);
                CustomChain chain = AnnotationUtils.findAnnotation(method, CustomChain.class);
                if (chain != null) {
                    System.out.println("--------->" + method + "  " + chain);
                }
            }, method -> null != AnnotationUtils.findAnnotation(method, CustomChain.class));
        }

    }

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        initChain();
    }
}
